<!-- 编辑弹窗 -->

<template>
  <ele-modal
    form
    :width="740"
    :model-value="modelValue"
    :title="isUpdate ? '编辑菜单' : '新增菜单'"
    @update:model-value="updateModelValue"
  >
    <el-form ref="formRef" :model="form" :rules="rules" label-width="92px">
      <el-row :gutter="16">
        <el-col :sm="12" :xs="24">
          <el-form-item label="上级菜单" prop="pid">
            <MenuSelect v-model="form.pid" :data="menuList" />
          </el-form-item>
          <el-form-item label="菜单名称" prop="title">
            <el-input v-model="form.title" clearable :maxlength="20" placeholder="请输入菜单名称" />
          </el-form-item>
        </el-col>
        <el-col :sm="12" :xs="24">
          <el-form-item label="菜单类型" prop="type">
            <el-radio-group v-model="form.type" @change="ontypeChange">
              <el-radio :value="2" label="目录" />
              <el-radio :value="0" label="菜单" />
              <el-radio :value="1" label="目按钮录" />
            </el-radio-group>
          </el-form-item>
          <el-form-item label="打开方式">
            <el-radio-group v-model="form.open_type" :disabled="form.type !== 0" @change="onOpenTypeChange">
              <el-radio :value="0" label="组件" />
              <el-radio :value="1" label="内链" />
              <el-radio :value="2" label="外链" />
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
      <el-divider style="margin: 8px 0 22px 0; opacity: 0.6" />
      <el-row :gutter="16">
        <el-col :sm="12" :xs="24">
          <el-form-item label="菜单图标" prop="icon">
            <IconSelect v-model="form.icon" :disabled="form.type === 1" />
          </el-form-item>
          <el-form-item prop="path">
            <template #label>
              <ele-tooltip v-if="form.open_type === 2" content="需要以`http://`、`https://`、`//`开头">
                <el-icon :size="16" style="align-self: center; margin-right: 4px; cursor: help">
                  <Warning style="opacity: 0.6" />
                </el-icon>
              </ele-tooltip>
              <span>{{ form.open_type === 2 ? '外链地址' : '路由地址' }}</span>
            </template>
            <el-input
              v-model="form.path"
              clearable
              :maxlength="100"
              :disabled="form.type === 1"
              :placeholder="form.open_type === 2 ? '请输入外链地址' : '请输入路由地址'
              "
            />
          </el-form-item>
          <el-form-item prop="component">
            <template #label>
              <ele-tooltip v-if="form.open_type === 1" content="需要以`http://`、`https://`、`//`开头">
                <el-icon :size="16" style="align-self: center; margin-right: 4px; cursor: help">
                  <Warning style="opacity: 0.6" />
                </el-icon>
              </ele-tooltip>
              <span>{{ form.open_type === 1 ? '内链地址' : '组件路径' }}</span>
            </template>
            <el-input
              v-model="form.component"
              clearable
              :maxlength="100"
              :disabled="form.type !== 0
                || form.open_type === 2
              "
              :placeholder="form.open_type === 1 ? '请输入内链地址' : '请输入组件路径'
              "
            />
          </el-form-item>
        </el-col>
        <el-col :sm="12" :xs="24">
          <el-form-item label="权限标识" prop="authority">
            <el-input
              v-model="form.authority"
              clearable
              placeholder="请输入权限标识"
              :disabled="form.type === 2
                || (form.type === 0 && form.open_type === 2)
              "
            />
          </el-form-item>
          <el-form-item label="日志名称" prop="name">
            <el-input
              v-model="form.name"
              clearable
              placeholder="请输入日志名称"
            />
          </el-form-item>
          <el-form-item label="排序号" prop="sort">
            <el-input-number
              v-model="form.sort"
              :min="0"
              :max="99999"
              placeholder="请输入排序号"
              controls-position="right"
              class="ele-fluid"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="是否展示">
        <el-switch
          inline-prompt
          active-text="是"
          inactive-text="否"
          :model-value="form.hide === 0"
          :disabled="form.type === 1"
          @change="updateHideValue"
        />
        <ele-tooltip content="选择不展示只注册路由不展示在侧边栏, 比如新增页面应该选择不展示" :popper-style="{ maxWidth: '240px' }">
          <el-icon :size="16" style="margin-left: 16px; cursor: help">
            <Warning style="opacity: 0.6" />
          </el-icon>
        </ele-tooltip>
      </el-form-item>
      <el-form-item label="路由元数据" prop="meta">
        <el-input v-model="form.meta" :rows="4" type="textarea" :maxlength="200" placeholder="请输入JSON格式的路由元数据" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="updateModelValue(false)">
        取消
      </el-button>
      <el-button type="primary" :loading="loading" @click="save">
        保存
      </el-button>
    </template>
  </ele-modal>
</template>

<script setup>
import { updateMenu } from '@/api/system/menu'
import IconSelect from '@/components/IconSelect/index.vue'
import { Warning } from '@element-plus/icons-vue'
import { isExternalLink } from 'ele-admin-plus/es'
import { reactive, ref, watch } from 'vue'
import MenuSelect from './menu-select.vue'

const props = defineProps({
  /** 弹窗是否打开 */
  modelValue: Boolean,
  /** 修改回显的数据 */
  data: Object,
  /** 新增时上级菜单id */
  pid: Number,

  menuList: Array,

  adminType: Number,
})

const emit = defineEmits(['done', 'update:modelValue'])

/** 是否是修改 */
const isUpdate = ref(false)

/** 提交状态 */
const loading = ref(false)

/** 表单实例 */
const formRef = ref(null)

/** 表单数据 */
const { form, resetFields, assignFields } = utils.useFormData({
  id: undefined,
  pid: undefined,
  title: '',
  type: 0,
  open_type: 0,
  icon: 'IconProDesktopOutlined',
  path: '',
  component: '',
  authority: '',
  sort: 0,
  hide: 0,
  meta: '',
  name: '',
})

/** 表单验证规则 */
const rules = reactive({
  title: [
    {
      required: true,
      type: 'string',
      message: '请输入菜单名称',
      trigger: 'blur',
    },
  ],
  sort: [
    {
      required: true,
      type: 'number',
      message: '请输入排序号',
      trigger: 'blur',
    },
  ],
  meta: [
    {
      type: 'string',
      validator: (_rule, value, callback) => {
        if (value) {
          const msg = '请输入正确的JSON格式'
          try {
            const obj = JSON.parse(value)
            if (obj == null || typeof obj !== 'object')
              return callback(msg)
          }
          catch (_e) {
            return callback(msg)
          }
        }
        callback()
      },
      trigger: 'blur',
    },
  ],
  name: [
    {
      required: true,
      type: 'string',
      message: '请输入日志名称',
      trigger: 'blur',
    },
  ],
})

/** 保存编辑 */
function save() {
  formRef.value?.validate?.((valid) => {
    if (!valid)
      return
    loading.value = true
    updateMenu({
      ...form,
      // type 对应的值与后端不一致在前端处理
      type: form.type === 1 ? 1 : 0,
      pid: form.pid || 0,
      admin_type: props.adminType,
    })
      .then((res) => {
        utils.message(res.msg, res.success)
        updateModelValue(false)
        emit('done')
      })
      .finally(() => {
        loading.value = false
      })
  })
}

/** 更新modelValue */
function updateModelValue(value) {
  emit('update:modelValue', value)
}

/** type选择改变 */
function ontypeChange() {
  if (form.type === 2) {
    form.authority = ''
    form.open_type = 0
    form.component = ''
  }
  else if (form.type === 0) {
    if (form.open_type === 2)
      form.authority = ''
  }
  else {
    form.open_type = 0
    form.icon = ''
    form.path = ''
    form.component = ''
    form.hide = 0
  }
}

/** open_type选择改变 */
function onOpenTypeChange() {
  if (form.open_type === 2) {
    form.component = ''
    form.authority = ''
  }
}

/** hide选择改变 */
function updateHideValue(value) {
  form.hide = value ? 0 : 1
}

/** 判断是否是目录 */
function isDirectory(d) {
  return !!d.children?.length && !d.component
}

watch(
  () => props.modelValue,
  (modelValue) => {
    if (modelValue) {
      if (props.data) {
        const isExternal = isExternalLink(props.data.path)
        const isInner = isExternalLink(props.data.component)
        // type对应的值与后端不一致在前端处理
        const type
          = props.data.type === 1 ? 1 : isDirectory(props.data) ? 2 : 0
        assignFields({
          ...props.data,
          type,
          open_type: isExternal ? 2 : isInner ? 1 : 0,
          pid: props.data.pid === 0 ? undefined : props.data.pid,
        })
        isUpdate.value = true
      }
      else {
        form.pid = props.pid
        isUpdate.value = false
      }
    }
    else {
      resetFields()
      formRef.value?.clearValidate?.()
    }
  },
)
</script>
